package com.mars.tukuan.utils.file.cloud;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import okhttp3.OkHttpClient;
import okhttp3.Request;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.qiniu.util.UrlSafeBase64;

/**
 * 七牛云存储，工具类
 * 
 * @author yhaoquan
 * 
 */
public class UploadCloudStroe {

	private Logger logger = LoggerFactory.getLogger(getClass()) ;
	
	// AccessKey
	private String accessKey;
	// SecretKey
	private String secretKey;
	// 空间名称
	private String bucket;
	// 外链默认域名
	private String domainOfBucket;

	/**
	 * 文件上传，上传本地文件
	 * @param file 	上传的文件对象
	 * @param dir	存放目录，目录不存在则自动创建（"weixin/media/image"）
	 * @return
	 * @throws QiniuException
	 */
	public UploadResult uploadFile(File file, String dir) throws QiniuException {
		String token = getToken();
		UploadManager uploadManager = getUploadManager();
		
		try {
			Response response = uploadManager.put(file, ((null != dir && StringUtils.isNotEmpty(dir) ? dir+"/" : "") + file.getName()), token);
			// 解析上传成功的结果
			DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
			logger.info("文件上传到云存储服务器：{}", putRet.key);
			
			return new UploadResult(true, putRet.key, getFileUrl(putRet.key), "上传成功") ;
		} catch (QiniuException ex) {
			Response r = ex.response;
			logger.error("文件上传到云存储服务器失败：{}", r.toString());
			return new UploadResult(false, r.toString()) ;
		}
	}
	
	
	/**
	 * 文件上传
	 * @param localFilePath	本地文件的路径
	 * @param dir			七牛上的文件存放目录，目录不存在则自动创建（"weixin/media/image"）
	 * @return
	 * @throws QiniuException
	 */
	public UploadResult uploadFile(String localFilePath, String dir) throws QiniuException {
		return uploadFile(new File(localFilePath), dir) ;
	}
	/**
	 * 文件上传
	 * @param file	本地文件的路径
	 * @return
	 * @throws QiniuException
	 */
	public UploadResult uploadFile(File file) throws QiniuException {
		return uploadFile(file, null) ;
	}
	/**
	 * 文件上传
	 * @param localFilePath	本地文件的路径
	 * @return
	 * @throws QiniuException
	 */
	public UploadResult uploadFile(String localFilePath) throws QiniuException {
		return uploadFile(new File(localFilePath), null) ;
	}
	
	/**
	 * 删除文件
	 * @param bucket 空间
	 * @param filename 文件名称
	 */
	public void deleteFile(String bucket, String filename) {
		//指定需要删除的空间和文件，格式为： <bucket>:<key>
		String entry = bucket + ":" + filename;
		//通过安全base64编码方式进行编码处理
		String encodedEntryURI = UrlSafeBase64.encodeToString(entry);
		//指定接口
        String target = "/delete/" + encodedEntryURI + "\n";
        //指定好请求的delete接口地址
        String url = "http://rs.qiniu.com/delete/" + encodedEntryURI;
        
        String access_token = getSignToken(target) ;
                
		// 通过Okhttp jar 包封装的对象 发起网络请求
		OkHttpClient client = new OkHttpClient();
		Request request = new Request.Builder().url(url)
				.addHeader("Content-Type", "application/x-www-form-urlencoded")
				.addHeader("Authorization", "QBox " + access_token).build();
		okhttp3.Response re = null;
		try {
			re = client.newCall(request).execute();
			if (re.isSuccessful() == true) {
				logger.info("[七牛云]-删除成功-状态码：[{}]-空间：[{}]，文件：[{}]", re.code(), bucket, filename);
			} else {
				logger.info("[七牛云]-删除失败-状态码：[{}]-空间：[{}]，文件：[{}]", re.code(), bucket, filename);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取文件下载URL
	 * @param filePath 文件路径（weixin/media/avatar.png）
	 * @return
	 */
	public String getFileUrl(String filePath) {
		try {
			String encodedFileName = URLEncoder.encode(filePath, "utf-8");
			String finalUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
			
			return finalUrl ;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 获取上传凭证
	 * 
	 * @return
	 */
	private String getToken() {
		Auth auth = getAuth();
		return auth.uploadToken(this.bucket) ;
	}
	
	/**
	 * 获取token，即操作凭证
	 * @return
	 */
	private String getSignToken(String target) {
		Auth auth = getAuth() ;
		return auth.sign(target) ;
	}

	/**
	 * 密钥验证
	 * @return
	 */
	private Auth getAuth() {
		Auth auth = Auth.create(accessKey, secretKey);
		return auth;
	}

	/**
	 * 获取文件删除对象
	 * @return
	 */
	private UploadManager getUploadManager() {
		UploadManager uploadManager = new UploadManager(getConfiguration());
		return uploadManager;
	}

	/**
	 * 指定文件上传的区域（华东，华北，华南，北美）
	 * @return
	 */
	private Configuration getConfiguration() {
		Configuration cfg = new Configuration(Zone.zone2());
		return cfg;
	}

	public void setAccessKey(String accessKey) {
		this.accessKey = accessKey;
	}

	public void setSecretKey(String secretKey) {
		this.secretKey = secretKey;
	}

	public void setBucket(String bucket) {
		this.bucket = bucket;
	}

	public void setDomainOfBucket(String domainOfBucket) {
		this.domainOfBucket = domainOfBucket;
	}

}
